#ifndef SKILLMODEL_H
#define SKILLMODEL_H

#include <QAbstractListModel>
#include <QMap>
#include <QUuid> // 用于生成唯一的技能树 ID
#include <QSettings>
#include <QStandardPaths>
#include <QDir>
#include <QVariantMap>
#include <QVariantList>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include "Skill.h"

// 定义单个技能树的数据结构
struct SkillTree {
    QUuid id;
    QString name;
    QString category; // 技能分类：数学、语文、运动、生活等
    QList<Skill> skills; // 该树包含的技能列表
    int nextId; // 下一个技能的ID
};

class SkillModel : public QAbstractListModel {
    Q_OBJECT
public:
enum SkillRoles {
    IdRole = Qt::UserRole + 1,
    NameRole,
    ParentRole,
    XRole,
    YRole,
    UnlockedRole,
    CompletedRole,
    SelectedRole,
    CategoryRole,
    DescriptionRole,
    DifficultyRole,
    ProgressRole,
    StarRatingRole,
    IsLevelRole,
    MaxStarRatingRole,
    MedalIconRole
};

    SkillModel(QObject *parent = nullptr);

    // QAbstractListModel 接口
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    QHash<int, QByteArray> roleNames() const override;

    // QML 暴露的方法
    Q_INVOKABLE void addSkill(QString name, int parentId = -1, QString category = "", QString description = "", int difficulty = 1, bool isLevel = false, int maxStarRating = 3, QString medalIcon = "");
    Q_INVOKABLE void unlockSkill(int skillId);
    Q_INVOKABLE void completeSkill(int skillId);
    Q_INVOKABLE void uncompleteSkill(int skillId);  // 取消完成技能
    Q_INVOKABLE void completeSkillWithStars(int skillId, int stars);  // 带星级完成技能
    Q_INVOKABLE int getSkillStarRating(int skillId);  // 获取技能星级
    Q_INVOKABLE void updateProgress(int skillId, int progress);
    Q_INVOKABLE void updateSkillName(int skillId, QString newName);
    Q_INVOKABLE void updateSkillTreeName(QString treeId, QString newName);
    Q_INVOKABLE void selectSkill(int skillId);
    Q_INVOKABLE void addChildSkill(int parentId, QString name);
    Q_INVOKABLE void addChildLevel(int parentId, QString name, int maxStars = 5, QString medalIcon = "");
    Q_INVOKABLE void deleteSkill(int skillId);
    Q_INVOKABLE int getSkillMaxStarRating(int skillId) const;
    Q_INVOKABLE QVariantList getAvailableMedalIcons() const;
    Q_INVOKABLE void saveData();
    Q_INVOKABLE void loadData();
    Q_INVOKABLE QVariantMap get(int index) const;
    
    // 云同步功能
    Q_INVOKABLE void setCloudSyncConfig(const QString& owner, const QString& repo, const QString& token);
    Q_INVOKABLE void syncFromCloud();  // 从云端下载
    Q_INVOKABLE void syncToCloud();    // 上传到云端
    Q_INVOKABLE void checkAndSyncOnStartup();  // 启动时检查冲突
    Q_INVOKABLE void checkAndSyncOnExit();     // 退出时检查冲突
    Q_INVOKABLE void clearModifiedFlag();      // 清除修改标志

    Q_INVOKABLE QString getDataFilePath() const;
    Q_INVOKABLE bool exportSkillTrees(const QString& destinationPath);
    Q_INVOKABLE bool importSkillTrees(const QString& sourcePath);

    // QML 暴露属性：当前激活的技能树ID (用于切换数据源)
    Q_PROPERTY(QString currentTreeId READ currentTreeId WRITE setCurrentTreeId NOTIFY currentTreeIdChanged)
    QString currentTreeId() const;
    void setCurrentTreeId(const QString& treeId);
    
    // QML 暴露属性：技能数量
    Q_PROPERTY(int count READ count NOTIFY countChanged)
    int count() const;

    // QML 暴露属性：数据修改状态
    Q_PROPERTY(bool dataModified READ hasDataModified NOTIFY dataModifiedChanged)
    bool hasDataModified() const;
    
    // QML 暴露属性：云同步配置是否有效
    Q_PROPERTY(bool cloudSyncValid READ isCloudSyncValid NOTIFY cloudSyncValidChanged)
    bool isCloudSyncValid() const;

    // QML 暴露方法：管理技能树集合
    Q_INVOKABLE QString createNewSkillTree(const QString& name, const QString& category = "", bool autoCreateRootNode = true);
    Q_INVOKABLE QVariantList getSkillTrees() const; // 返回所有技能树的列表 {id, name, category}
    Q_INVOKABLE void deleteSkillTree(const QString& treeId); // 删除指定的技能树
    Q_INVOKABLE void refreshPlayerStats();

signals:
    void currentTreeIdChanged();
    void countChanged();
    void dataModifiedChanged();
    void cloudSyncValidChanged();
    
    // 云同步信号
    void syncStarted();
    void syncSuccess(QString message);
    void syncFailed(QString errorMsg);
    
    // 冲突检测信号
    void cloudDataDifferent(QString cloudHash, QString localHash);  // 启动时云端数据不同
    void localDataDifferent(QString localHash, QString cloudHash);  // 退出时本地数据不同
    void dataConsistent();  // 数据一致（退出检查时使用）

    // 玩家统计信息
    void playerStatsUpdated(int totalPoints, int totalStars);
    void levelMedalEarned(const QString& treeId, int skillId, QString skillName, QString medalIcon);
    void levelMedalRevoked(const QString& treeId, int skillId);
    void levelMedalUpdated(const QString& treeId, int skillId, QString skillName, QString medalIcon);

private:
    // 存储所有技能树
    QMap<QString, SkillTree> m_skillTrees;
    QString m_currentTreeId;
    
    // 云同步相关
    QNetworkAccessManager* m_networkManager;
    QString m_giteeOwner;
    QString m_giteeRepo;
    QString m_giteeToken;
    QString m_currentFileSha;  // 用于更新文件
    bool m_autoSyncEnabled;
    bool m_cloudSyncValid;     // 云同步配置是否有效（格式验证通过）
    bool m_dataModified;       // 数据修改标志位
    
    // 云同步辅助函数
    void markDataAsModified();  // 标记数据已修改
    QString getCloudApiUrl() const;
    void handleDownloadReply(QNetworkReply* reply);
    void handleUploadReply(QNetworkReply* reply);
    bool isCloudSyncConfigured() const;
    bool validateCloudSyncConfig() const;  // 验证云同步配置的有效性
    void validateRepository();  // 验证仓库是否存在（异步）
    void handleRepositoryValidationReply(QNetworkReply* reply);  // 处理仓库验证响应
    QString calculateDataHash() const;  // 计算当前数据的哈希值
    QString calculateHashFromJson(const QJsonObject& rootObj) const;  // 从JSON对象计算哈希
    void handleStartupCheckReply(QNetworkReply* reply);  // 处理启动检查响应
    void handleExitCheckReply(QNetworkReply* reply);     // 处理退出检查响应

    // 辅助函数
    void collectChildrenSkills(int parentId, QList<int>& children);
    void rearrangeChildrenInLayer(int yLevel);  // 重新排列同层级的节点，按父节点分组（旧方法）
    void rearrangeSkillTree();  // 改进的树形布局算法：重新排列整个技能树
    void arrangeChildren(Skill* parent, 
                        QMap<int, QList<Skill*>>& childrenMap,
                        QMap<int, int>& subtreeWidth,
                        int startX,
                        int currentY,
                        int levelHeight,
                        int groupSpacing,
                        QMap<int, int>& absoluteX);  // 递归排列子节点
    
    // 辅助函数，获取当前激活的 SkillTree 对象的引用
    SkillTree& currentSkillTree();
    const SkillTree& currentSkillTree() const;

    // 辅助函数，确保模型列表操作发生在正确的索引范围
    void beginResetCurrentModel();
    void endResetCurrentModel();
    
    // 初始化默认儿童技能树（仅在构造函数中使用）
    void initializeDefaultChildrenSkills();

    // 玩家统计
    void updatePlayerStats();
};

#endif // SKILLMODEL_H
